package com.kky.pp.activity.login.phone

import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.core.widget.addTextChangedListener
import com.custom.base.config.BaseConfig
import com.custom.base.entity.OkHttpBodyEntity
import com.custom.base.http.OkHttpFromBoy
import com.custom.base.http.OkHttpManager
import com.custom.base.http.SDOkHttpResoutCallBack
import com.custom.base.util.ToastUtil
import com.google.firebase.FirebaseException
import com.google.firebase.FirebaseTooManyRequestsException
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.PhoneAuthCredential
import com.google.firebase.auth.PhoneAuthOptions
import com.google.firebase.auth.PhoneAuthProvider
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
import com.kky.pp.common.Constant
import com.kky.pp.R
import com.kky.pp.base.TitleBasePresenterImpl
import com.kky.pp.entity.IMTokenGetEntity
import com.kky.pp.entity.LoginParamEntity
import com.kky.pp.http.CommonHttpResutHead
import com.kky.pp.rongyun.RongConfigUtil
import com.kky.pp.activity.register.RegisterActivity
import com.kky.pp.util.SoftInputUtils
import com.kky.pp.util.SystemUtils
import com.kky.pp.view.Loading.LoadingDialog
import com.kky.pp.view.codeview.VerificationCodeView
import com.custom.base.base.SDEventManager
import io.rong.imkit.SpName
import io.rong.imkit.event.EnumEventTag
import java.util.concurrent.TimeUnit


class PhoneLoginPresenter : TitleBasePresenterImpl<PhoneLoginContract.View>(),
    PhoneLoginContract.Presenter {

    private var storedVerificationId: String = ""
    private var resendToken: PhoneAuthProvider.ForceResendingToken? = null
    private lateinit var callbacks: PhoneAuthProvider.OnVerificationStateChangedCallbacks
    private var mCredential: PhoneAuthCredential? = null
    private var smsCodeShow: Boolean = false
    var auth = Firebase.auth
    private var receiveCode: Boolean = false
    var mBundle: Bundle? = null

    @SuppressLint("ResourceAsColor")
    override fun initBundle(bundle: Bundle) {
        mView?.apply {
            mBundle = bundle
//            SoftInputUtils.showSoftInput(editPhone, InputType.TYPE_CLASS_NUMBER)
            editPhone.addTextChangedListener {
                phoneNext.isEnabled = editPhone.text.toString().isNotEmpty()
                phoneNextContainer.setBackgroundResource(if (editPhone.text?.isNotEmpty() == true)R.drawable.ic_button_bg_radius_25 else R.drawable.ic_button_bg_radius_25_unable)
            }
            phoneNextContainer.setOnClickListener {
                if (SystemUtils.isConnected(mActivity)) {
                    if (editPhone.text.toString().length < 10) {
                        showToast(mActivity.getString(R.string.phone_number_error))
                        return@setOnClickListener
                    }
                    textLoginPhone.text = "+1${editPhone.text}"
                    SoftInputUtils.hideSoftInput(editPhone)
                    phoneNextAnim.visibility = View.VISIBLE
                    phoneNextAnim.playAnimation()
                    if (resendToken == null) {
                        startPhoneNumberVerification(textLoginPhone.text.toString())
                    } else {
                        resendVerificationCode(textLoginPhone.text.toString(), resendToken)
                    }
                } else {
                    ToastUtil.toast(mActivity.getString(R.string.ooops_network_error))
                }

            }
            actLoginCode.setOnClickListener {
                resendCodeAnim.visibility = View.VISIBLE
                resendCodeAnim.playAnimation()
                if (resendToken == null) {
                    startPhoneNumberVerification(textLoginPhone.text.toString())
                } else {
                    resendVerificationCode(textLoginPhone.text.toString(), resendToken)
                }

            }
            actLoginCode.addTextChangedListener {
                bottomLine.setBackgroundColor(
                    if (actLoginCode.isSend) ContextCompat.getColor(
                        mActivity,
                        R.color.color_999999
                    ) else ContextCompat.getColor(mActivity, R.color.color_202323)
                )
            }
            editCode.setInputCompleteListener(object : VerificationCodeView.InputCompleteListener {
                override fun inputComplete() {
                    codeNext.isEnabled = editCode.inputContent.isNotEmpty()
                    codeNextContainer.isEnabled = editCode.inputContent.isNotEmpty()
                    codeNextContainer.setBackgroundResource(if (editCode.inputContent.isNotEmpty()) R.drawable.ic_button_bg_radius_25 else R.drawable.ic_button_bg_radius_25_unable)
                }

                override fun deleteContent() {
                    codeNext.isEnabled = editCode.inputContent.isNotEmpty()
                    codeNextContainer.isEnabled = editCode.inputContent.isNotEmpty()
                    codeNextContainer.setBackgroundResource(if (editCode.inputContent.isNotEmpty()) R.drawable.ic_button_bg_radius_25 else R.drawable.ic_button_bg_radius_25_unable)
                }

            })
            codeNextContainer.setOnClickListener {

                if (editCode.inputContent.length < 6) {
                    showToast("code error")
                    return@setOnClickListener
                }
                codeNextAnim.visibility = View.VISIBLE
                codeNextAnim.playAnimation()
                if (mCredential != null) {
                    signInWithPhoneAuthCredential(mCredential!!)
                } else {
                    if (storedVerificationId != "") {
                        val credential = PhoneAuthProvider.getCredential(
                            storedVerificationId,
                            editCode.inputContent
                        )
                        signInWithPhoneAuthCredential(credential)
                    }
                }
                SoftInputUtils.hideSoftInput(editCode)
            }
            callbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
                override fun onVerificationCompleted(credential: PhoneAuthCredential) {
                    val inputStr = credential.smsCode
                    val strArray: Array<String> =
                        (inputStr?.split("".toRegex())?.dropLastWhile { it.isEmpty() }
                            ?.toTypedArray()
                            ?: arrayOf())

                    for (i in strArray.indices) {
                        editCode.setText(strArray[i])
                    }
                    mCredential = credential
                }

                override fun onVerificationFailed(e: FirebaseException) {
                    LoadingDialog.dismissLoading(mActivity)
                    phoneNextAnim.visibility = View.GONE
                    resendCodeAnim.visibility = View.GONE
                    when (e) {
                        is FirebaseAuthInvalidCredentialsException -> {
                            // Invalid request
                            showToast(mActivity.getString(R.string.code_expire_error))
                        }

                        is FirebaseTooManyRequestsException -> {
                            // The SMS quota for the project has been exceeded
                            showToast("Failed to send the verification code. Please use another login method")
                        }

                    }

                }

                override fun onCodeSent(
                    verificationId: String,
                    token: PhoneAuthProvider.ForceResendingToken,
                ) {
                    receiveCode = true
                    // Save verification ID and resending token so we can use them later
                    storedVerificationId = verificationId
                    resendToken = token
                    actLoginCode.startTime()
                    if (phoneOutsideContainer.isVisible) {
                        phoneOutsideContainer.visibility = View.GONE
                        codeOutsideContainer.visibility = View.VISIBLE
                        phoneNextAnim.visibility = View.GONE
                        phoneNextAnim.pauseAnimation()
                        smsCodeShow = true
                        //获取焦点自动弹出软键盘
                        editCode.et.requestFocus();
                        val imm =
                            mActivity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                        imm.showSoftInput(editCode.et, 0)
                    } else {
                        resendCodeAnim.visibility = View.GONE
                        resendCodeAnim.pauseAnimation()
                    }

                }

                override fun onCodeAutoRetrievalTimeOut(verificationId: String) {
                    Log.e("~~~", "onCodeAutoRetrievalTimeOut: $verificationId")
                }

            }
        }

        super<TitleBasePresenterImpl>.initBundle(bundle)
    }

    override fun onBackClick() {
        onBackListener()
    }

    private fun loginPhone(user: FirebaseUser?) {
        mView?.apply {
            OkHttpManager.instance.requestInterface(object : OkHttpFromBoy {
                override fun addBody(requestBody: OkHttpBodyEntity) {
                    if (mBundle?.getString("source") == null) {
                        requestBody.setPost(Constant.login_Url)
                        requestBody.add("loginType", 1)
                    } else {
                        requestBody.setPost(Constant.account_bind_Url)
                        requestBody.add("accountType", 1)
                    }
                    requestBody.add("account", user?.uid ?: "")
                    requestBody.add("mobile", textLoginPhone.text.toString())
                }

            }, object : SDOkHttpResoutCallBack<LoginParamEntity>() {
                override fun onSuccess(entity: LoginParamEntity) {
                    if (mBundle?.getString("source") == null) {
                        BaseConfig.getInstance.addHead("basicParams", CommonHttpResutHead.getHead(entity.data.token).toString())
                        BaseConfig.getInstance.setString(SpName.token, entity.data.token)
                        BaseConfig.getInstance.setString(SpName.userCode, entity.data.userCode)
                        if (entity.data.nickName != null) {
                            BaseConfig.getInstance.setString(SpName.nickName, entity.data.nickName)
                        }
                        if (entity.data.avatarUrl != null) {
                            BaseConfig.getInstance.setString(
                                SpName.avatarUrl,
                                entity.data.avatarUrl
                            )
                        }
                        BaseConfig.getInstance.setBoolean(
                            SpName.profileComplete,
                            entity.data.isUserValid
                        )
                        if (entity.data.isUserValid) {
                            OkHttpManager.instance.requestInterface(object : OkHttpFromBoy {
                                override fun addBody(requestBody: OkHttpBodyEntity) {
                                    requestBody.setPost(Constant.im_token_Url)
                                }
                            }, object : SDOkHttpResoutCallBack<IMTokenGetEntity>() {
                                override fun onSuccess(parms: IMTokenGetEntity) {
                                    RongConfigUtil.connectIMLogin(
                                        parms.data.token,
                                        entity.data.userCode,
                                        entity.data.nickName,
                                        entity.data.avatarUrl ?: ""
                                    )
                                }

                                override fun onFailure(code: Int, msg: String) {
                                }
                            })
                        } else {
                            startActivity(RegisterActivity::class.java)
                            finish()
                        }
                    } else {
                        SDEventManager.post(EnumEventTag.MY_ACCOUNT_REFRESH.ordinal)
                        finish()
                    }
                }

                override fun onFailure(code: Int, msg: String) {
                    mView?.apply {
                        codeNextAnim.visibility = View.GONE
                        codeNextAnim.pauseAnimation()
                    }
                    showToast(msg)
                }

            })
        }

    }

    private fun startPhoneNumberVerification(phoneNumber: String) {
        val options = PhoneAuthOptions.newBuilder(auth)
            .setPhoneNumber(phoneNumber) // Phone number to verify
            .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
            .setActivity(mActivity) // Activity (for callback binding)
            .setCallbacks(callbacks) // OnVerificationStateChangedCallbacks
            .build()
        PhoneAuthProvider.verifyPhoneNumber(options)
        // [END start_phone_auth]
    }

    private fun resendVerificationCode(
        phoneNumber: String,
        token: PhoneAuthProvider.ForceResendingToken?,
    ) {
        val optionsBuilder = PhoneAuthOptions.newBuilder(auth)
            .setPhoneNumber(phoneNumber) // Phone number to verify
            .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
            .setActivity(mActivity) // (optional) Activity for callback binding
            .setCallbacks(callbacks) // OnVerificationStateChangedCallbacks
        if (token != null) {
            optionsBuilder.setForceResendingToken(token) // callback's ForceResendingToken
        }
        PhoneAuthProvider.verifyPhoneNumber(optionsBuilder.build())
    }


    private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
        auth.signInWithCredential(credential)
            .addOnCompleteListener(mActivity) { task ->
                receiveCode = false
                if (task.isSuccessful) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.e("~~~", "signInWithCredential:success")

                    val user = task.result?.user
                    Log.e("~~~", "signInWithCredential:${user?.uid}")
                    loginPhone(user)

                } else {
                    mView?.apply {
                        codeNextAnim.visibility = View.GONE
                        codeNextAnim.pauseAnimation()
                    }

                    if (task.exception is FirebaseAuthInvalidCredentialsException) {
                        if ((task.exception as FirebaseAuthInvalidCredentialsException).errorCode == "ERROR_INVALID_VERIFICATION_CODE") {
                            showToast("code error")
                        } else {
                            showToast(task.exception?.message.toString())
                        }
                        // The verification code entered was invalid
                    }
                    // Update UI
                }
            }
    }

    fun onBackListener() {
        mView?.apply {
            if (smsCodeShow) {
                editCode.clearInputContent()
                phoneOutsideContainer.visibility = View.VISIBLE
                codeOutsideContainer.visibility = View.GONE
                codeNextAnim.visibility = View.GONE
                codeNextAnim.pauseAnimation()
                actLoginCode.isSend = false
                smsCodeShow = false
            } else {
                mActivity.finish()
            }
        }


    }

}